package com.tjhk.geoserver.api.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tjhk.geoserver.api.config.GeoserverProperties;
import com.tjhk.geoserver.api.entity.Layer;
import com.tjhk.geoserver.api.model.LayerInfo;
import com.tjhk.geoserver.api.service.GeoServer;
import com.tjhk.geoserver.api.service.LayerService;
import com.tjhk.geoserver.api.util.FileUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import it.geosolutions.geoserver.rest.decoder.RESTLayer;
import it.geosolutions.geoserver.rest.decoder.RESTLayerList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Api(tags = "图层发布")
@CrossOrigin
@RestController
@RequestMapping
public class TiffPublish {

    @Autowired
    private GeoserverProperties geoserverProperties;
    @Autowired
    private LayerService layerService;
    @PostMapping("/test")
    @ApiOperation(value = "test")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "zipFile", value = "zip文件", paramType = "form", dataType = "__file"),
            @ApiImplicitParam(name = "styleFile", value = "style文件", paramType = "form", dataType = "__file"),
    })
    public boolean test(
            @RequestParam(value = "zipFile") MultipartFile zipFile,
            @RequestParam(value = "styleFile") MultipartFile styleFile) {

        String layerName = zipFile.getOriginalFilename().replaceAll("[.][^.]+$", "");
        String styleName = styleFile.getOriginalFilename().replaceAll("[.][^.]+$", "");
        File file1 = multipartFileToFile(styleFile);
        File file2 = multipartFileToFile(zipFile);
        System.out.println(file2.getAbsolutePath());
        try {

            File f=new File("/root/geoserver/tmp");
            f.setWritable(true, false);    //设置写权限，windows下不用此语句
            f.mkdirs();
            FileUtil.copyFile(file2,"\\root\\geoserver-api\\tmp\\"+layerName+".zip");
            FileUtil.unZipFiles(file2,"\\root\\geoserver-api\\tmp");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
    @PostMapping("/publishShpAStyle")
    @ApiOperation(value = "发布Shp和SID样式")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "zipFile", value = "zip文件", paramType = "form", dataType = "__file"),
            @ApiImplicitParam(name = "styleFile", value = "style文件", paramType = "form", dataType = "__file"),
    })
    public boolean publishShpAStyle(
            @RequestParam(value = "zipFile") MultipartFile zipFile,
            @RequestParam(value = "styleFile") MultipartFile styleFile) {

        String layerName = zipFile.getOriginalFilename().replaceAll("[.][^.]+$", "");
        String styleName = styleFile.getOriginalFilename().replaceAll("[.][^.]+$", "");
        File file1 = multipartFileToFile(styleFile);
        File file2 = multipartFileToFile(zipFile);
        String workplace = "test01";
        GeoServer geoServer = new GeoServer(geoserverProperties);
        boolean publishStyle = geoServer.publishStyle(workplace,styleName,file1);

        String randomLayerName = UUID.randomUUID().toString().replaceAll("-","");
        boolean publishShp = geoServer.publicShp(workplace, file2,randomLayerName, styleName);


        RESTLayer layer = geoServer.manager.getReader().getLayer(workplace, randomLayerName);
        if (layer!=null){
            Layer layerInfo = new Layer(layerName,
                    geoserverProperties.getUrl()+"/"+workplace+"/wms?",
                    workplace+":"+layer.getName(),
                    geoserverProperties.getUrl()+"/"+workplace+"/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer="+workplace+":"+layer.getName(),
                    LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
            );
            layerService.save(layerInfo);
        }

        return publishStyle&publishShp;
    }


    @PostMapping("/publishGeoTifAStyle")
    @ApiOperation(value = "发布GeoTif和SID样式")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tifFile", value = "tif文件", paramType = "form", dataType = "__file"),
            @ApiImplicitParam(name = "styleFile", value = "style文件", paramType = "form", dataType = "__file"),
    })
    public boolean publishGeoTifAStyle(
            @RequestParam(value = "tifFile") MultipartFile tifFile,
            @RequestParam(value = "styleFile") MultipartFile styleFile) {

        String layerName = tifFile.getOriginalFilename().replaceAll("[.][^.]+$", "");
        String styleName = styleFile.getOriginalFilename().replaceAll("[.][^.]+$", "");
        File file1 = multipartFileToFile(styleFile);
        File file2 = multipartFileToFile(tifFile);
        String workplace = "test01";
        GeoServer geoServer = new GeoServer(geoserverProperties);
        geoServer.publishStyle(workplace,styleName,file1);
        boolean flag = geoServer.isExistStyle(workplace,styleName);
        if (flag){
            if (geoServer.isExistLayer(workplace,layerName)){
                System.out.println("图层存在！");
                return false;
            }
            boolean publish = geoServer.publicTiff(workplace,
                    layerName,
                    layerName,
                    file2,
                    styleName);
            return publish;
        }
        return false;
    }

    @PostMapping("/publishGeoTif")
    @ApiOperation(value = "发布GeoTif-样式已存在")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tifFile", value = "tif文件", paramType = "form", dataType = "__file"),
            @ApiImplicitParam(name = "styleName", value = "图层样式名称", dataType = "String")
    })
    public boolean publishGeoTifAStyle(
            @RequestParam(value = "tifFile") MultipartFile tifFile,
            @RequestParam(value = "styleName") String styleName) {

        String layerName = tifFile.getOriginalFilename().replaceAll("[.][^.]+$", "");
        File file2 = multipartFileToFile(tifFile);
        String workplace = "test01";
        GeoServer geoServer = new GeoServer(geoserverProperties);
        boolean flag = geoServer.isExistStyle(workplace,styleName);
        if (flag){
            if (geoServer.isExistLayer(workplace,layerName)){
                System.out.println("图层存在！");
                return false;
            }
            boolean publish = geoServer.publicTiff(workplace,
                    layerName,
                    layerName,
                    file2,
                    styleName);
            return publish;
        }
        return false;
    }

    @PostMapping("/publishBaseGeoTif")
    @ApiOperation(value = "发布GeoTif")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tifFile", value = "tif文件", paramType = "form", dataType = "__file")
    })
    public boolean uploadGeoTif(
            @RequestParam(value = "tifFile") MultipartFile tifFile) {

        String layerName = tifFile.getOriginalFilename().replaceAll("[.][^.]+$", "");
        File file = multipartFileToFile(tifFile);
        String workplace = "test01";
        GeoServer geoServer = new GeoServer(geoserverProperties);
        geoServer.publicTiff(workplace,layerName,file);
        return false;
    }

    @GetMapping("/getLayers")
    @ApiOperation(value = "获取所有图层")
    public List<LayerInfo> getLayers() {

        List<Layer> list= layerService.list(new LambdaQueryWrapper<Layer>()
                .select(Layer::getLayerName,Layer::getName)
        );
        list.forEach(s->{
            System.out.println(s.getLayerName()+s.getName());
        });
        Map<String,String> layerMap = layerService.list(new LambdaQueryWrapper<Layer>()
                .select(Layer::getLayerName,Layer::getName)
        ).stream().collect(Collectors.toMap(Layer::getLayerName,Layer::getName));

        GeoServer geoServer = new GeoServer(geoserverProperties);
        List<LayerInfo> res = new ArrayList<>();
        RESTLayerList layerList = geoServer.manager.getReader().getLayers();
        layerList.forEach(s->{
            String[] names = s.getName().split(":");
            RESTLayer layer = geoServer.manager.getReader().getLayer(names[0], URLEncoder.encode(names[1]));
            LayerInfo layerInfo = new LayerInfo(layer.getName(),
                    geoserverProperties.getUrl()+"/"+names[0]+"/wms?",
                    s.getName(),
                    geoserverProperties.getUrl()+"/"+names[0]+"/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer="+s.getName());
            if (layerMap.get(s.getName())!=null){
                layerInfo.setName(layerMap.get(s.getName()));
            }
            res.add(layerInfo);
        });
        return res;
    }

    @PostMapping("/delLayerAStore")
    @ApiOperation(value = "删除数据仓库")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeName", value = "存储仓库名称", dataType = "String")
    })
    public boolean delStore(
            String storeName
    ) {
        GeoServer geoServer = new GeoServer(geoserverProperties);
        String workplace = "test01";
        return geoServer.deleteStore(workplace,storeName);
    }

    @PostMapping("/delLayer")
    @ApiOperation(value = "删除图层")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "layerName", value = "图层名称", dataType = "String")
    })
    public boolean delLayer(
            String layerName
    ) {
        GeoServer geoServer = new GeoServer(geoserverProperties);
        String workplace = "test01";
        return geoServer.deleteLayer(workplace,layerName);
    }

    public static File multipartFileToFile(MultipartFile multiFile) {
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
//        if (StringUtils.isNullOrEmpty(fileName)) {
//            return null;
//        }
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        try {
            File file = File.createTempFile(fileName, prefix);
            multiFile.transferTo(file);
            return file;
        } catch (Exception e) {
//            log.error("MultipartFile转换为File转换异常：" + e.getMessage());
        }
        return null;
    }

//    private void setAuth(HttpClient client, String url, String username, String pw)
//            throws MalformedURLException {
//        URL u = new URL(url);
//        if (username != null && pw != null) {
//            Credentials defaultcreds = new UsernamePasswordCredentials(username, pw);
//            client.getState().setCredentials(new AuthScope(u.getHost(), u.getPort()), defaultcreds);
//            client.getParams().setAuthenticationPreemptive(true); // GS2 by
//            // default
//            // always
//            // requires
//            // authentication
//        } else {
//        }
//    }
//    @GetMapping("/publishtif")
//    public void publish() throws Exception {
//        //GeoServer的连接配置
//        String url = "http://localhost:8080/geoserver";
//        String username = "admin";
//        String passwd = "geoserver";
//
//        String ws = "test01";     //待创建和发布图层的工作区名称workspace
//        //String store_name = "tiffTest"; //待创建和发布图层的数据存储名称store
//
//        //判断工作区（workspace）是否存在，不存在则创建
//        URL u = new URL(url);
//        GeoServerRESTManager manager = new GeoServerRESTManager(u, username, passwd);
//        GeoServerRESTPublisher publisher = manager.getPublisher();
//        List<String> workspaces = manager.getReader().getWorkspaceNames();
//        if (!workspaces.contains(ws)) {
//            boolean createws = publisher.createWorkspace(ws);
//            System.out.println("create ws : " + createws);
//        } else {
//            System.out.println("workspace已经存在了,ws :" + ws);
//        }
//
//        //判断数据存储（datastore）是否已经存在，不存在则创建
//        //String fileName = "F:\\Document\\Graduation Project\\MapData\\Tiff\\beijing.tif";
//
//
//        /*遍历文件夹路径下tiff文件*/
//        //String path = "F:\\Document\\Graduation Project\\MapData\\Tiff";		//要遍历的路径
//        String path = tiffurl;
//        System.out.println(tiffurl);
//        File file = new File(path);		//获取其file对象
//        File[] fs = file.listFiles();	//遍历path下的文件和目录，放在File数组中
//
//        String store_name; //待创建和发布图层的数据存储名称store
//        String fileName;
//        for(File f : fs)
//        {
//            if(f.isFile())
//            {
//                if (f.getName().endsWith(".tif")) {
//                    // 就输出该文件的绝对路径
//                    //System.out.println(f.getAbsolutePath());
//                    store_name = f.getName().replaceAll("[.][^.]+$", "");
//                    fileName = f.getAbsolutePath();
//                    RESTDataStore restStore = manager.getReader().getDatastore(ws, store_name);
//                    if (restStore == null) {
//                        GSGeoTIFFDatastoreEncoder gsGeoTIFFDatastoreEncoder = new GSGeoTIFFDatastoreEncoder(store_name);
//                        gsGeoTIFFDatastoreEncoder.setWorkspaceName(ws);
//                        gsGeoTIFFDatastoreEncoder.setUrl(new URL("file:" + fileName));
//                        boolean createStore = manager.getStoreManager().create(ws, gsGeoTIFFDatastoreEncoder);
//                        System.out.println("create store (TIFF文件创建状态) : " + createStore);
//                        boolean publish = manager.getPublisher().publishGeoTIFF(ws, store_name, new File(fileName));
//                        System.out.println("publish (TIFF文件发布状态) : " + publish);
//                        //System.out.println(f.getName() + " : 发布成功！");
//                    } else {
//                        System.out.println("数据存储已经存在了,store:" + store_name);
//                    }
//                }
//            }
//        }
//
//        //验证tiff文件是否全部上传至GeoServer
//        /*for (File f : fs){
//            if(f.isFile()) {
//                if (f.getName().endsWith(".tif")) {
//                    store_name = f.getName().replaceAll("[.][^.]+$", "");
//                    RESTDataStore restStore = manager.getReader().getDatastore(ws, store_name);
//                    if (restStore != null){
//                        System.out.println(f.getName() + " : 发布成功！");
//                    }
//                    else {
//                        System.out.println("[warn] "+f.getName() + " : 发布失败！");
//                    }
//                }
//            }
//        }*/
//    }
//
//    @PostMapping("/publishtreetif")
//    public void publishtree(@RequestBody String ws) throws Exception {
//        //GeoServer的连接配置
//        String url = "http://localhost:8080/geoserver";
//        String username = "admin";
//        String passwd = "geoserver";
//
//        ws = ws.substring(0,ws.length()-1);
//
//        //String ws = "test01";     //待创建和发布图层的工作区名称workspace
//        //String store_name = "tiffTest"; //待创建和发布图层的数据存储名称store
//
//        //判断工作区（workspace）是否存在，不存在则创建
//        URL u = new URL(url);
//        GeoServerRESTManager manager = new GeoServerRESTManager(u, username, passwd);
//        GeoServerRESTPublisher publisher = manager.getPublisher();
//        List<String> workspaces = manager.getReader().getWorkspaceNames();
//        if (!workspaces.contains(ws)) {
//            boolean createws = publisher.createWorkspace(ws);
//            System.out.println("create ws : " + createws);
//        } else {
//            System.out.println("workspace已经存在了,ws :" + ws);
//        }
//
//        //判断数据存储（datastore）是否已经存在，不存在则创建
//        //String fileName = "F:\\Document\\Graduation Project\\MapData\\Tiff\\beijing.tif";
//
//
//        /*遍历文件夹路径下tiff文件*/
//        //String path = "F:\\Document\\Graduation Project\\MapData\\Tiff";		//要遍历的路径
//        String path = tiffurl;
//        System.out.println(tiffurl);
//        File file = new File(path);        //获取其file对象
//        File[] fs = file.listFiles();    //遍历path下的文件和目录，放在File数组中
//
//        String store_name; //待创建和发布图层的数据存储名称store
//        String fileName;
//        for (File f : fs) {
//            if (f.isFile()) {
//                if (f.getName().endsWith(".tif")) {
//                    // 就输出该文件的绝对路径
//                    //System.out.println(f.getAbsolutePath());
//                    store_name = f.getName().replaceAll("[.][^.]+$", "");
//                    fileName = f.getAbsolutePath();
//                    RESTDataStore restStore = manager.getReader().getDatastore(ws, store_name);
//                    if (restStore == null) {
//                        GSGeoTIFFDatastoreEncoder gsGeoTIFFDatastoreEncoder = new GSGeoTIFFDatastoreEncoder(store_name);
//                        gsGeoTIFFDatastoreEncoder.setWorkspaceName(ws);
//                        gsGeoTIFFDatastoreEncoder.setUrl(new URL("file:" + fileName));
//                        boolean createStore = manager.getStoreManager().create(ws, gsGeoTIFFDatastoreEncoder);
//                        System.out.println("create store (TIFF文件创建状态) : " + createStore);
//                        boolean publish = manager.getPublisher().publishGeoTIFF(ws, store_name, new File(fileName));
//                        System.out.println("publish (TIFF文件发布状态) : " + publish);
//                        //System.out.println(f.getName() + " : 发布成功！");
//                    } else {
//                        System.out.println("数据存储已经存在了,store:" + store_name);
//                    }
//                }
//            }
//        }
//    }

}